package com.hksj.acm.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.hksj.acm.dto.HistoryCurveDTO;
import com.hksj.acm.mapper.DeviceHistoryDataMapper;
import com.hksj.acm.vo.*;
import com.hksj.cbm.dto.DeviceDTO;
import com.hksj.cbm.entity.DeviceInstance;
import com.hksj.cbm.entity.DeviceMetadataParseInfo;
import com.hksj.cbm.mapper.DeviceMetadataParseInfoMapper;
import com.hksj.cbm.service.DeviceInstanceService;
import com.hksj.cbm.vo.DeriveMetadataVO;
import com.hksj.cbm.vo.SpaceModelVO;
import com.hksj.common.core.common.Constants;
import com.hksj.common.core.common.SpecialityModelCodeEnum;
import com.hksj.tdengine.taos.service.TaosService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author fjt
 * @data 2024/7/10 15:18
 * @describe 设备列表
 */
@Slf4j
@Service
public class DeviceService {

    @Autowired
    private DeviceInstanceService deviceInstanceService;
    @Autowired
    private DeviceCoreParamConfigService deviceCoreParamConfigService;
    @Autowired
    private DeviceMetadataParseInfoMapper deviceMetadataParseInfoMapper;
    @Autowired
    private DeviceHistoryDataMapper deviceHistoryDataMapper;
    @Autowired
    private TaosService taosService;

    private static final String running_state = "Jizyx";


    /**
     * 设备列表查询(不带检测指标数据)
     * @param dto
     * @return
     */
    public List<DeviceVO> deviceWithoutDataList(DeviceDTO dto){
        // 查询指定空间位置下的全部设备
        dto.setCode(SpecialityModelCodeEnum.air_conditioning.getCode());
        List<DeviceInstance> deviceInstanceList = deviceInstanceService.deviceList(dto);
        if (CollUtil.isEmpty(deviceInstanceList)){
            return null;
        }

        // 查询设备的完整路径
        Map<String, List<SpaceModelVO>> pathNameMap = new HashMap<>();
        List<String> devicePathList = deviceInstanceList.stream().map(DeviceInstance::getPaths).collect(Collectors.toList());
        if (CollUtil.isNotEmpty(devicePathList)){
            pathNameMap = deviceInstanceService.devicePathConvertToUTF8(devicePathList);
        }

        // 组装数据，设置每个设备的空间位置节点信息
        List<DeviceVO> deviceVOList = new ArrayList<>(deviceInstanceList.size());
        for (DeviceInstance instance : deviceInstanceList){
            DeviceVO vo = new DeviceVO();
            vo.setDeviceId(instance.getId());
            vo.setDeviceName(instance.getName());
            // 设备在线/离线状态
            vo.setState(instance.getState());
            vo.setPhotoUrl(instance.getPhotoUrl());
            vo.setProductId(instance.getProductId());
            vo.setPaths(instance.getPaths());
            if (CollUtil.isNotEmpty(pathNameMap)){
                List<SpaceModelVO> spaceModelVOList = pathNameMap.get(instance.getPaths());
                if (CollUtil.isNotEmpty(spaceModelVOList)){
                    Map<String, String> spaceNameMap = spaceModelVOList.stream()
                            .collect(Collectors.toMap(p -> p.getSpaceItemValue(), p -> p.getModelName()));
                    // 楼栋-楼层
                    StringBuilder builder = new StringBuilder(spaceNameMap.get(Constants.FOUR_STR));
                    if (StringUtils.isNotBlank(spaceNameMap.get(Constants.THREE_STR))){
                        builder.append("-").append(spaceNameMap.get(Constants.THREE_STR));
                    }
                    vo.setPathName(builder.toString());
                }
                // 后续(下方的deviceList(DeviceDTO dto)方法)其他地方调用此方法时需要这个数据
                vo.setSpaceModelVOList(spaceModelVOList);
            }
            deviceVOList.add(vo);
        }
        return deviceVOList;
    }


    /**
     * 设备列表查询(同时查询设备配置的全部监测数据)
     * @param dto
     * @return
     */
    public List<DeviceVO> deviceList(DeviceDTO dto){
        // 1.获取设备列表
        List<DeviceVO> deviceList = deviceWithoutDataList(dto);
        if (CollUtil.isEmpty(deviceList)){
            return null;
        }
        List<String> deviceIdList = deviceList.stream().map(DeviceVO::getDeviceId).collect(Collectors.toList());


        // 2.获取每个设备检测指标的当前值
        LambdaQueryWrapper<DeviceMetadataParseInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(DeviceMetadataParseInfo::getDeviceId, deviceIdList);
        List<DeviceMetadataParseInfo> deviceMetadataParseInfoList = deviceMetadataParseInfoMapper.selectList(queryWrapper);
        // 按设备id把监测数据分组
        Map<String, List<DeviceMetadataParseInfo>> deviceMap = deviceMetadataParseInfoList.stream()
                .collect(Collectors.groupingBy(DeviceMetadataParseInfo::getDeviceId));
        // 获取每个监测指标的中文名称
        Map<String, Map<String, DeriveMetadataVO>> attributeMap = deviceInstanceService.batchQueryDeviceAttribute(deviceIdList);

        // 获取设备每个监测指标property对应的中文名称，并逆推出每个设备的正常/报警状态
        for (DeviceVO deviceVO : deviceList){
            // 3.处理设备路径
            List<SpaceModelVO> spaceModelVOList = deviceVO.getSpaceModelVOList();
            if (CollUtil.isNotEmpty(spaceModelVOList)){
                Map<String, String> spaceNameMap = spaceModelVOList.stream()
                        .collect(Collectors.toMap(p -> p.getSpaceItemValue(), p -> p.getModelName()));
                // 楼栋-楼层-房间-点位
                StringBuilder builder = new StringBuilder(spaceNameMap.get(Constants.FOUR_STR));
                if (StringUtils.isNotBlank(spaceNameMap.get(Constants.THREE_STR))){
                    builder.append("-").append(spaceNameMap.get(Constants.THREE_STR));
                }
                if (StringUtils.isNotBlank(spaceNameMap.get(Constants.TWO_STR))){
                    builder.append("-").append(spaceNameMap.get(Constants.TWO_STR));
                }
                if (StringUtils.isNotBlank(spaceNameMap.get(Constants.ONE_STR))){
                    builder.append("-").append(spaceNameMap.get(Constants.ONE_STR));
                }
                deviceVO.setPathName(builder.toString());
            }

            // 4.获取设备的每个指标的中文名称和监测值
            Map<String, DeriveMetadataVO> deviceTargetMap = attributeMap.get(deviceVO.getDeviceId());
            List<DeviceMetadataParseInfo> parseInfoList = deviceMap.get(deviceVO.getDeviceId());
            if (CollUtil.isEmpty(parseInfoList)){
                continue;
            }

            // 监测指标报警状态  0正常1报警
            String alarmStatus = Constants.ZERO_STR;
            List<DeviceAttributeVO> attributeList = new ArrayList<>(parseInfoList.size());
            for(DeviceMetadataParseInfo parseInfo : parseInfoList){
                String property = parseInfo.getProperty();

                // 获取每个指标的中文名称和监测值
                DeviceAttributeVO attributeVO = DeviceAttributeVO.builder().key(property).unit(parseInfo.getUnit()).value(parseInfo.getValue()).build();
                if (CollUtil.isNotEmpty(deviceTargetMap)){
                    DeriveMetadataVO metadataVO = deviceTargetMap.get(parseInfo.getProperty());
                    attributeVO.setKeyName(ObjectUtil.isNotNull(metadataVO) ? metadataVO.getKeyName() : null);
                }
                attributeList.add(attributeVO);

                // 5.处理设备的运行状态
                if (running_state.equals(property)){
                    deviceVO.setRunningState(parseInfo.getValue());
                }
                // key以特定的bj字符结尾，有任意一个监测指标是报警状态，则该设备的报警状态为报警
                if (parseInfo.getProperty().endsWith("bj") && Constants.ONE_STR.equals(parseInfo.getValue())){
                    alarmStatus = Constants.ONE_STR;
                }
            }
            deviceVO.setAlarmStatus(alarmStatus);
            deviceVO.setAttributeList(attributeList);
        }
        return deviceList;
    }


    /**
     * 查询指定设备的全部监测指标数据
     * @return
     */
    public List<DeviceAttributeVO> monitorDataByDeviceId(String deviceId){
        Map<String, DeriveMetadataVO> attributeMap = deviceInstanceService.getDeviceAttribute(deviceId);
        //监测数据
        LambdaQueryWrapper<DeviceMetadataParseInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DeviceMetadataParseInfo::getDeviceId, deviceId);
        List<DeviceMetadataParseInfo> deviceMetadataParseInfoList = deviceMetadataParseInfoMapper.selectList(queryWrapper);
        if (CollUtil.isNotEmpty(deviceMetadataParseInfoList)){

            List<DeviceAttributeVO> voList = new ArrayList<>(deviceMetadataParseInfoList.size());
            deviceMetadataParseInfoList.forEach(parseInfo -> {
                DeviceAttributeVO attributeVO = new DeviceAttributeVO();
                attributeVO.setKey(parseInfo.getProperty());
                attributeVO.setUnit(parseInfo.getUnit());
                DeriveMetadataVO metadataVO = attributeMap.get(parseInfo.getProperty());
                if (ObjectUtil.isNotNull(metadataVO)){
                    attributeVO.setKeyName(metadataVO.getKeyName());
                }
                attributeVO.setValue(parseInfo.getValue());
                voList.add(attributeVO);
            });
            return voList;
        }
        return null;
    }


    /**
     * 查询指定设备的核心参数监测数据
     * @param deviceId
     * @return
     */
    public List<CoreParamMonitorDataVO> queryCoreParamMonitorData(String deviceId){
        // 查询当前设备配置的核心参数
        List<DeviceCoreParamConfigVO> coreParamConfigVOList = deviceCoreParamConfigService.queryDeviceCoreParamConfigByDeviceId(deviceId);
        if (CollUtil.isEmpty(coreParamConfigVOList)){
            return null;
        }
        List<String> keyList = coreParamConfigVOList.stream().map(DeviceCoreParamConfigVO::getProperty).collect(Collectors.toList());
        // 查询这些指标当前的监测值
        LambdaQueryWrapper<DeviceMetadataParseInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DeviceMetadataParseInfo::getDeviceId, deviceId);
        queryWrapper.in(DeviceMetadataParseInfo::getProperty, keyList);
        List<DeviceMetadataParseInfo> deviceMetadataParseInfoList = deviceMetadataParseInfoMapper.selectList(queryWrapper);
        // 指标key:指标监测信息
        Map<String, DeviceMetadataParseInfo> parseInfoMap = deviceMetadataParseInfoList.stream().collect(Collectors.toMap(p -> p.getProperty(), p -> p));

        List<CoreParamMonitorDataVO> dataVOList = new ArrayList<>(coreParamConfigVOList.size());
        for (DeviceCoreParamConfigVO configVO : coreParamConfigVOList){
            CoreParamMonitorDataVO dataVO = new CoreParamMonitorDataVO();
            BeanUtils.copyProperties(configVO, dataVO);
            dataVO.setKey(configVO.getProperty());
            dataVO.setKeyName(configVO.getPropertyName());

            DeviceMetadataParseInfo parseInfo = parseInfoMap.get(configVO.getProperty());
            if(ObjectUtil.isNotNull(parseInfo)) {
                dataVO.setUnit(parseInfo.getUnit());
                dataVO.setValue(parseInfo.getValue());
            }
            dataVOList.add(dataVO);
        }
        return dataVOList;
    }



    /**
     * 指定设备的历史曲线查询
     * @param dto
     * @return
     */
    public List<HistoryCurveVO> queryHistoryCurve(HistoryCurveDTO dto){

        //查询当前设备的物模型属性信息
        Map<String, DeriveMetadataVO> attributeMap = deviceInstanceService.getDeviceAttribute(dto.getDeviceId());

        if (CollUtil.isEmpty(dto.getPropertyList())){
            // 查询全部温度和湿度相关的指标
            if (CollUtil.isNotEmpty(attributeMap)){
                List<String> propertyList = new ArrayList<>();
                attributeMap.keySet().forEach(key -> {
                    if (key.endsWith("wd") || key.endsWith("sd")){
                        propertyList.add(key);
                    }
                });
                dto.setPropertyList(propertyList);
            }
        }
        if (CollUtil.isEmpty(dto.getPropertyList())){
            return null;
        }

        // 获取当前设备的历史检测数据所在的TDengine表名
        DeviceInstance deviceInstance = deviceInstanceService.getById(dto.getDeviceId());
        if (ObjectUtil.isNull(deviceInstance) || StringUtils.isBlank(deviceInstance.getProductId())){
            throw new RuntimeException("此设备不存在或没有指定其所属的产品");
        }

        List<HistoryCurveVO> resultList = new ArrayList<>();
        String tableName = String.format("properties_%S", deviceInstance.getProductId());
        //判断表是否存在
        Boolean existStable = taosService.checkStable("jetlinks_clean_room", tableName);
        if (existStable){
            List<HistoryDataVo> dataVoList = deviceHistoryDataMapper.queryHistoryCurve(dto, "jetlinks_clean_room." + tableName);
            if (CollUtil.isEmpty(dataVoList)){
                return resultList;
            }
            Map<String, List<HistoryDataVo>> map = dataVoList.stream().collect(Collectors.groupingBy(HistoryDataVo::getProperty));
            for(Map.Entry<String, List<HistoryDataVo>> entry : map.entrySet()){
                HistoryCurveVO historyCurveVO = HistoryCurveVO.builder()
                        .property(entry.getKey())
                        .propertyName(attributeMap.get(entry.getKey()).getKeyName())
                        .unit(attributeMap.get(entry.getKey()).getUnit())
                        .list(entry.getValue()).build();
                resultList.add(historyCurveVO);
            }
        }
        return resultList;
    }






}






